<?php
# Change this to point to the PHPXMLRPC server.php
require_once("../../XMLRPC/PHPXMLRPC/server.php");
#Include core mantis files
$mantis_dir = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR;
$g_bypass_headers = true;
require_once($mantis_dir . 'core.php');

#Include helper functions
require_once("mantishelper.php");

# Convert this file into an XMLRPC server
$mantis_server = new PHPXMLRPCServer();
$mantis_server->addFunction("MantisRPC", "MantisRPC");
$mantis_server->startServer();


function MantisRPC($args){
	
	//print_r($args);
	
	$args_count = $args->getNumParams();
	
	$username = $args->getParam(0);
	$password = $args->getParam(1);
	$function = $args->getParam(2);
	
	$func_args = array();

	for($i = 3; $i < $args_count; $i++){
		$temp = $args->getParam($i);
		$func_args[] = $temp->scalarval();
	}
	
	if(!MantisLogin($username->scalarval(), $password->scalarval())){
		return XMLRPCError("Invalid user and pass");
	}

	if(!in_array($function->scalarval(), getRemoteFunctions())){
		return XMLRPCError("Function not found in Remote List");	
	}
	
	$result = call_user_func_array($function->scalarval(), $func_args);
	
	return new xmlrpcresp(processResult($result));
	
}

function XMLRPCError($msg){
	global $xmlrpcerruser;
	
	return new xmlrpcresp(0, $xmlrpcerruser, $msg);
}


function MantisLogin($username, $password){
	
	$offline_file = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'mantis_offline.php';
	if(file_exists( $offline_file )){
		return false;
	}

	# if no user name supplied, then attempt to login as anonymous user.
	if(is_blank($username)){
		
		$anon_allowed = config_get('allow_anonymous_login');
		
		if($anon_allowed == "OFF"){
			return false;
		}

		$username = config_get('anonymous_account');

		# do not use password validation.
		$password = null;
	}

	if(auth_attempt_script_login($username, $password) === false){
		return false;
	}

	return true;
}

function is_associative_array($array) {
	if(!is_array($array) || empty($array)){
		return false;
	}

	$keys = array_keys($array);
	return array_keys($keys) !== $keys;
	
}

function getRemoteFunctions(){
	$func = array();
	
	#mantis native core functions
	$func[] = "user_get_accessible_projects";
	$func[] = "bug_get_field";
	$func[] = "bug_exists";
	$func[] = "bug_get";
	$func[] = "bug_create";
	$func[] = "project_get_id_by_name";
	$func[] = "filter_get_bug_rows";
	$func[] = "project_create";
	
	#mantis helper functions
	$func[] = "getMantisBugByProjectID";
	$func[] = "getMantisBugByProjectName";
	$func[] = "updateMantisBugStatusById";
	$func[] = "getMantisBugById";
	$func[] = "addExtraBugData";
	$func[] = "bugCreateHelper";
	
	return $func;
}

function processResult($result){
	
	$ret = new xmlrpcval();

	if(is_object($result)){
		$result = get_object_vars($result);
	}
	
	if(is_associative_array($result)){
		
		$ar = array();
		
		$keys = array_keys($result);

		foreach($keys as $k){

			$tmp = new xmlrpcval(array($k => new xmlrpcval($result[$k])), 'struct');	
			$ar[] = $tmp;			
		}
		
		$ret->addArray($ar);
	}
	else if(is_array($result)){
		foreach($result as $key => $value){
			
			if(!is_string($value)){
				$tmp = processResult($value);
			}
			else {
				$tmp = new xmlrpcval();
				$tmp->addScalar($value);
			}
			
			$result[$key] = $tmp;
		}
		
		$ret->addArray($result);
	}
	else if(is_bool($result)){
		$ret->addScalar($result, "boolean");
	}
	else {
		$ret->addScalar($result);
	}
	
	return $ret;
}	
